/****************************************************************************
 * Copyright (C) 2009-2011 Dimok
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ****************************************************************************/
#ifndef _APPLICATION_H
#define _APPLICATION_H

#include <queue>

#include "../GUI/gui.h"
#include "WiiPointer.h"
#include "CMutex.h"
#include "../Prompts/ScreenSaver.hpp"

class ThreadedTask;

class Application : public GuiFrame, public sigslot::has_slots<>
{
	public:
		static Application * Instance() { if(!instance) instance = new Application(); return instance; }
		static void DestroyInstance() { delete instance; instance = NULL; }
		
		void init();
		void quit();
		void exec();
		void show();
		void hide();
		void updateEvents();
		static void shutdownSystem() { bShutdown = true; }
		static void resetSystem() { bReset = true; }
		static bool isClosing() { return exitApplication; }
		static void closeRequest() { exitApplication = true; }
		
		static void setReload(short type) { instance->FadeOut(); reloading = true; reloadType = type; }
		static bool isReloading() {  return reloading; }
		static bool isReloadingTheme() {  return (reloadType == RELOAD_THEME); }
		static bool isReloadingLang() {  return (reloadType == RELOAD_LANG); }
		static bool isReloadingFont() {  return (reloadType == RELOAD_FONT); }
		static bool isReloadingDefault() {  return (reloadType == RELOAD_DEFAULT); }
		void Reload() { needReload = true; }
		void ExecuteReload();
		
		enum
		{
			RELOAD_NONE,
			RELOAD_THEME,
			RELOAD_LANG,
			RELOAD_FONT,
			RELOAD_DEFAULT,
		};
		
		void ResetPads();
		void Append(GuiElement *e);
		void PushForDelete(GuiElement *e);
		void SetGuiInputUpdate(bool b) { bGuiInputUpdate = b; }
		void SetUpdateOnly(GuiElement *e);
		void UnsetUpdateOnly(GuiElement *e);
		void addPostRenderTask(ThreadedTask *t);
		
		WiiPointer *pointer[4];
		
	private:
		Application();
		virtual ~Application();
		
		void FadeIn();
		void FadeOut();
		
		void OnHomeButtonClick(GuiButton *sender, int pointer, const POINT &p);
		void OnHomeMenuClosing(GuiFrame *menu);
		void OnScreenSaverClosing(GuiFrame *saver);
		
		void ProcessDeleteQueue(void);
		void ProcessPostUpdateTasks(void);
		
		static Application *instance;
		static bool exitApplication;
		static bool bReset;
		static bool bShutdown;
		
		static bool needReload;
		static bool reloading;
		static short reloadType;
		
		ScreenSaver *screenSaver;
		GuiButton *btnHome;
		GuiTrigger trigHome;
		
		std::vector<GuiElement *> updateOnlyElement;
		std::vector<GuiElement *> deleteList;
		std::queue<ThreadedTask *> postUpdateTasks;
		CMutex m_mutex;
		bool bGuiInputUpdate;
};

#endif
